package com.mjh.manager;

import java.util.ArrayList;
import java.util.Date;
import org.apache.log4j.Logger;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.impl.StdSchedulerFactory;
import com.mjh.bean.Task;
import com.mjh.dao.TaskDAO;
import com.mjh.comm.*;

public class TaskManager {

	public static Logger log = Logger.getLogger(TaskManager.class);
	
	private static final String GROUP = "group";
	
	private ArrayList<Task> tasks;
	
	private Scheduler taskSchedule;
	
	private static TaskManager taskManager = new TaskManager();
	
	private TaskManager(){
		loadTask();
	}
	
	private void loadTask(){
		try {
			taskSchedule = null;
			tasks = null;
			taskSchedule = new StdSchedulerFactory().getScheduler();
			tasks = new TaskDAO().getTaskList();
			JobDetail job;
			CronTrigger trigger;
			for(Task t : tasks){
				job = new JobDetail(t.getId(), GROUP, Class.forName(t.getClassPath()));
				trigger = new CronTrigger("trig_" + t.getId(), GROUP, t.getId(), GROUP, t.getSchedule());
				taskSchedule.addJob(job, true);
		        taskSchedule.scheduleJob(trigger);
		        t.setRunning(true);
		        t.setNextExcuteDate(trigger.getNextFireTime());
			}
			taskSchedule.start();
		} catch (Exception e) {
			log.error("loadTask scheduler fail!", e);
		}
	}
	
	public static TaskManager getInstance(){
		return taskManager;
	}

	public ArrayList<Task> getTasksList(){
		return tasks;
	}
	
	public void setTaskRunningState(String taskId, boolean isRunning){
		if(taskId == null) return;
		for(Task t : tasks){
			if(t.getId().equals(taskId)){
				t.setRunning(isRunning);
				break;
			}
		}
	}
	
	public void setTaskLastExcuteState(String taskId, int state){
		if(taskId == null) return;
		for(Task t : tasks){
			if(t.getId().equals(taskId)){
				t.setLastExcuteState(state);
				break;
			}
		}
	}

	public void setTaskLastExcuteDate(String taskId, Date lastExcuteDate){
		if(taskId == null) return;
		for(Task t : tasks){
			if(t.getId().equals(taskId)){
				t.setLastExcuteDate(lastExcuteDate);
				break;
			}
		}
	}
	
	public void setTaskNextExcuteDate(String taskId, Date nextExcuteDate){
		if(taskId == null) return;
		for(Task t : tasks){
			if(t.getId().equals(taskId)){
				t.setNextExcuteDate(nextExcuteDate);
				break;
			}
		}
	}
	
	public int startTask(String taskId) {
		try {
			taskSchedule.resumeJob(taskId, GROUP);
			setTaskRunningState(taskId, true);
		} catch (SchedulerException e) {
			log.error("start task "+taskId+" fail!", e);
			return Constant.FAIL;
		}
		return Constant.SUCCESS;
	}
	
	public int stopTask(String taskId) {
		try {
			taskSchedule.pauseJob(taskId, GROUP);
			setTaskRunningState(taskId, false);
		} catch (SchedulerException e) {
			log.error("stop task "+taskId+" fail!", e);
			return Constant.FAIL;
		}
		return Constant.SUCCESS;
	}
	
	public int excuteTask(String taskId) {
		try {
			taskSchedule.triggerJob(taskId, GROUP);
		} catch (SchedulerException e) {
			log.error("excute task "+taskId+" fail!", e);
			return Constant.FAIL;
		}
		return Constant.SUCCESS;
	}
	
	public int startAll() {
		try {
			taskSchedule.resumeAll();
			for(Task t : tasks){
				t.setRunning(true);
			}
		} catch (SchedulerException e) {
			log.error("start All task fail!", e);
			return Constant.FAIL;
		}
		return Constant.SUCCESS;
	}
	
	public int stopAll () {
		try {
			taskSchedule.pauseAll();
			for(Task t : tasks){
				t.setRunning(false);
			}
		} catch (SchedulerException e) {
			log.error("stop All task fail!", e);
			return Constant.FAIL;
		}
		return Constant.SUCCESS;
	}
	
	public int reloadTask(){
		stopAll();
		try {
			for(Task t : tasks){
				taskSchedule.deleteJob(t.getId(), GROUP);
			}
			tasks.clear();
			taskSchedule.shutdown(false);
			loadTask();
		} catch (Exception e) {
			log.error("reloadTask fail!", e);
			return Constant.FAIL;
		}
		return Constant.SUCCESS;	
	}
}
